/*
 * @(#)CodeManager.java $version 2011. 10. 14
 * 
 * Copyright 2011 NHN Corp. All rights Reserved.
 * NHN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.hangame.mbl.util;

import java.io.InputStream;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.collections.BidiMap;
import org.apache.commons.collections.map.ListOrderedMap;
import org.apache.commons.digester.CallMethodRule;
import org.apache.commons.digester.Digester;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.nhncorp.lucy.common.data.DataHandler;
import com.nhncorp.lucy.common.data.DataHandlerFactory;

// TODO: Auto-generated Javadoc
/**
 * The Class CodeManager.
 * 
 * @author KR14386
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
public class CodeManager {
	
	/** The log. */
	private static Log log = LogFactory.getLog(CodeManager.class);
	
	/** The code map. */
	private static Map codeMap = null;
	
	/**
	 * Instantiates a new code manager.
	 */
	protected CodeManager() {
		throw new UnsupportedOperationException();
	}
	
	static {
		Digester digester = new Digester();
		digester.setValidating(false);

		digester.addObjectCreate("code", HashMap.class);

		digester.addObjectCreate("code/map", DualLinkedBidiMap.class);
		digester.addRule("code/map", new CallMethodRule(1, "put", 2));
		digester.addCallParam("code/map", 0, "id");
		digester.addCallParam("code/map", 1, true);

		digester.addObjectCreate("code/map/entry", StringBuffer.class);
		digester.addCallMethod("code/map/entry", "append", 1);
		digester.addCallParam("code/map/entry", 0);

		digester.addRule("code/map/entry", new CallMethodRule(1, "put", 2));
		digester.addCallParam("code/map/entry", 0, "key");
		digester.addCallParam("code/map/entry", 1);

		try {
			InputStream is = null;

			DataHandler conf = DataHandlerFactory.getDataHandler();
			
			if (conf.containsKey("code-manager")) {
				List includes = conf.getValues("code-manager/code-file");
				log.debug("code file size : " + includes.size());

				for (int i = 0; i < includes.size(); i++) {
					log.debug("code file name : " + includes.get(i));
					
					is = CodeManager.class.getClassLoader().getResourceAsStream((String)includes.get(i));
					
					if (is != null) {
						if (codeMap == null) {
							codeMap = (Map)digester.parse(is);
						} else {
							codeMap.putAll((Map)digester.parse(is));
						}
					}
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		if (codeMap == null) {
			log.debug("no use codeManager.");
		} else {
			log.debug("code=" + codeMap.toString());
		}
	}

	/**
	 * Gets the name by code.
	 * 
	 * @param category String
	 * @param code String
	 * @return String
	 */
	public static String getNameByCode(String category, String code) {
		BidiMap bidiMap = (BidiMap)codeMap.get(category);

		if (null == bidiMap) {
			return "";
		}

		return (String)bidiMap.get(code);
	}

	/**
	 * Gets the code by name.
	 * 
	 * @param category String
	 * @param name String
	 * @return String
	 */
	public static String getCodeByName(String category, String name) {
		BidiMap bidiMap = (BidiMap)codeMap.get(category);

		if (null == bidiMap) {
			return "";
		}

		return (String)bidiMap.getKey(name);
	}

	/**
	 * Gets the codes.
	 * 
	 * @param category String
	 * @return Collection
	 */
	public static Collection getCodes(String category) {
		Object categoryObject = (BidiMap)codeMap.get(category);
		
		if (categoryObject != null) {
			return ((BidiMap)categoryObject).keySet();
		} else {
			return null;
		}
	}

	/**
	 * Gets the names.
	 * 
	 * @param category String
	 * @return Collection
	 */
	public static Collection getNames(String category) {
		Object categoryObject = (BidiMap)codeMap.get(category);
		
		if (categoryObject != null) {
			return ((BidiMap)categoryObject).values();
		} else {
			return null;
		}
	}

	/**
	 * Gets the code map.
	 * 
	 * @param category String
	 * @return Map
	 */
	public static Map getCodeMap(String category) {
		Map codemap = (Map)codeMap.get(category);
		ListOrderedMap temp = new ListOrderedMap();
		
		if (codemap != null) {
			Set keys = codemap.keySet();
			String key = "";
			
			for (Iterator iter = keys.iterator(); iter.hasNext();) {
				key = (String)iter.next();
				temp.put(key, codemap.get(key));
			}
		}
		
		return temp;
	}
}
